﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://www.codeplex.com/EmlenMud
using System;
using System.Xml.Serialization;
using System.Text;
using System.Threading;
using System.ComponentModel;
using System.Collections;
using System.Collections.Generic;
using BrainTechLLC.ThreadSafeObjects;
using System.Runtime.Serialization;
#if USE_HYPER
using Hyper.ComponentModel;
#endif

namespace BrainTechLLC
{
	public class EventToPerceive : IEventToPerceive
	{
		protected AssociatedIDCollection _sources;
		protected AssociatedIDCollection _targets;
		public IEvent _event;

		[NonSerialized, XmlIgnore]
		public List<ICanBeNotified> _targetCache;

		[NonSerialized, XmlIgnore]
		public List<ICanBeNotified> _sourceCache;

		public void ToAudience(AssociatedIDCollection chars)
		{
			List<IEventPerceiver> perceivers = chars.ReadItems<IEventPerceiver>();
			for (int n = 0; n < perceivers.Count; n++)
			{
				IEventPerceiver perceiver = perceivers[n];
				ShowEvent(perceiver);
			}
		}

		public virtual bool ShowEvent(IEventPerceiver showTo)
		{
			IEvent evt = GetPerceivedEvent(showTo);
            
            if (evt == null)
                throw new Exception("No perceived event for " + showTo.AssociatedID.ToString());

			if (showTo.CanPerceive(this, evt.ViewType))
			{
				INotificationMessage result = showTo.PerceiveEvent(this);
				if (result != null)
				{
					showTo.Notify(result);
					return true;
				}
			}

			return false;
		}

		public List<ICanBeNotified> TargetObjects
		{
			get
			{
				if (_targetCache == null)
					_targetCache = Everything.Find<ICanBeNotified>(Targets);

				return _targetCache;
			}
		}


		public List<ICanBeNotified> SourceObjects
		{
			get
			{
				if (_sourceCache == null)
					_sourceCache = Everything.Find<ICanBeNotified>(Sources);

				return _sourceCache;
			}
		}

		public AssociatedIDCollection Sources
		{
			get
			{
				if (_sources == null)
					Interlocked.CompareExchange<AssociatedIDCollection>(ref _sources, new AssociatedIDCollection(), null);
				return _sources;
			}
			set
			{
				_sources = value;
			}
		}

        public bool HasTargets
        {
            get
            {
                if (_targets == null)
                    return false;

                return _targets.Count > 0;
            }
        }

		public AssociatedIDCollection Targets
		{
			get
			{
				if (_targets == null)
					Interlocked.CompareExchange<AssociatedIDCollection>(ref _targets, new AssociatedIDCollection(), null);

				return _targets;
			}
			set
			{
				_targets = value;
			}
		}
		public virtual IEvent GetPerceivedEvent(IEventPerceiver showTo) { return _event; }
	}
}